// 镜头眩光效果
// https://threejs.org/docs/#examples/zh/objects/Lensflare

import { 
  AmbientLight,
  BoxGeometry,
  Color,
  ImageUtils,
  Mesh,
  MeshLambertMaterial,
  PCFSoftShadowMap, 
  PerspectiveCamera, 
  Scene, SpotLight, SpotLightHelper, sRGBEncoding, 
  TextureLoader, 
  Vector3, 
  WebGLRenderer 
} from "three"
import { Lensflare, LensflareElement } from 'three/examples/jsm/objects/Lensflare'
import dat from 'dat.gui'
import Stats from 'stats.js'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'

const scene = new Scene()
const camera = new PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000)
camera.position.set(-20, 10, 45)
camera.lookAt(new Vector3(10, 0, 0))

const renderer = new WebGLRenderer({
  alpha: true,
  antialias: true
})
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setClearColor(0x000000)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
// 柔和阴影
renderer.shadowMap.type = PCFSoftShadowMap
// https://threejs.org/docs/#examples/zh/loaders/GLTFLoader
renderer.outputEncoding = sRGBEncoding

document.body.appendChild(renderer.domElement)

const ambiColor = '#1c1c1c'
const ambientLight = new AmbientLight(ambiColor)
scene.add(ambientLight)

const textureLoader = new TextureLoader()
const textureFlares0 = textureLoader.load('/img/light/lensflare0.png')
const textureFlares1 = textureLoader.load('/img/light/lensflare1.png')

const flareColor = new Color(0xffaacc)
// 创建镜头眩光
const lensFlare = new Lensflare()

lensFlare.addElement(new LensflareElement(textureFlares0, 350, 0.0, flareColor))
lensFlare.addElement(new LensflareElement(textureFlares1, 60, 0.6, flareColor))
lensFlare.addElement(new LensflareElement(textureFlares1, 70, 0.7, flareColor))
lensFlare.addElement(new LensflareElement(textureFlares1, 120, 0.9, flareColor))
lensFlare.addElement(new LensflareElement(textureFlares1, 70, 1, flareColor))

const spotLight = new SpotLight(0xffffff, 1.5, 200)
spotLight.position.set(30, 10, -50)
// 对光源添加镜头眩光
spotLight.add(lensFlare)
scene.add(spotLight)

const spotLightHelper = new SpotLightHelper(spotLight)
scene.add(spotLightHelper)

const cubeGeometry = new BoxGeometry(4, 4, 4)
const cubeMaterial = new MeshLambertMaterial({
  color: 0xff3333
})
const cube = new Mesh(cubeGeometry, cubeMaterial)
cube.position.set(-4, 3, 0)
scene.add(cube)

const trackballControls: TrackballControls = new TrackballControls(camera, renderer.domElement)
const stats: Stats = new Stats()
stats.showPanel(0)
document.body.appendChild(stats.dom)

const controls = {
  rotationSpeed: 0.03,
  ambientColor: ambiColor,
  spotColor: spotLight.color.getStyle(),
  distensity: 1.5 
}

const gui = new dat.GUI()
gui.addColor(controls, 'ambientColor').onChange(e => {
  spotLight.color = new Color(e)
})
gui.addColor(controls, 'spotColor').onChange(e => {
  spotLight.color = new Color(e)
})

function render() {
  stats.update()
  trackballControls.update()

  cube.rotation.x += controls.rotationSpeed
  cube.rotation.y += controls.rotationSpeed
  cube.rotation.z += controls.rotationSpeed

  requestAnimationFrame(render)
  renderer.render(scene, camera)
}
render()